﻿/**

 * Copyright (c) 2015-2016, FastDev 刘强 (fastdev@163.com).

 *

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *      http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

using OF.DistributeService.Core.Attribute;
using OF.DistributeService.Core.Client;
using OF.DistributeService.Core.Common;
using OF.DistributeService.Core.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ZooKeeperNet;

namespace TestOpenRestClient
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.ThreadException += Application_ThreadException;
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;
            Application.ApplicationExit += Application_ApplicationExit;
            Application.Run(new ClientDemo());
        }

        private static void TestSafeCall()
        {
            MockSafeCall(3, -2);
            MockSafeCall(3, -1);
            MockSafeCall(3, 0);
            MockSafeCall(3, 1);
            MockSafeCall(3, 2);
            MockSafeCall(3, 3);
            MockSafeCall(3, 4);
            MockSafeCall(3, 5);
        }

        private static void MockSafeCall(int maxLoop, int maxThrowI)
        {
           
            int indexI = 0;
            bool isTrue = Util.SafeLoopUtilTrue((loopI) =>
            {
                MockException(indexI++, maxThrowI);
                return 5 == indexI;
            }, maxLoop, 10);
            System.Diagnostics.Debug.WriteLine("MockSafeCall " + isTrue + ",LoopI:" + indexI + ":(" + maxLoop + "," + maxThrowI + ")");
            
            System.Diagnostics.Debug.WriteLine("\n\n");
        }

        private static void TestRetry()
        {
            MockTestRetry(3, -2);
            MockTestRetry(3, -1);
            MockTestRetry(3, 0);
            MockTestRetry(3, 1);
            MockTestRetry(3, 2);
            MockTestRetry(3, 3);
            MockTestRetry(3, 4);
            MockTestRetry(3, 5);
        }

        private static void MockTestRetry(int maxLoop, int maxThrowI)
        {
            try
            {
                int indexI = 0;
                int resultI = Util.MaxRetryCall(() =>
                {
                    MockException(indexI++, maxThrowI);
                    return indexI;
                }, maxLoop, 10);
                System.Diagnostics.Debug.WriteLine("MockTestRetry Result:" + resultI + ":(" + maxLoop + "," + maxThrowI + ")");
            }
            catch (Exception ex)
            {
                Util.LogException("MockTestRetry", ex);
                System.Diagnostics.Debug.WriteLine("MockTestRetry Exception:"+ maxLoop + "," + maxThrowI);
            }
            System.Diagnostics.Debug.WriteLine("\n\n");
        }

        private static void MockException(int index, int maxThrowI)
        {
            if (index <= maxThrowI)
            {
                throw new Exception();
            }
        }
        public static void InitAppServices()
        {
            ClientToAppConfig estTestApp = new ClientToAppConfig
            {
                ServiceAppName = "DonetOFDistributeServiceTest",
                ServiceList = OFDistributeServiceAttribute.GetClientToAppConfigList(typeof(TestOpenRestClient.Api.ISOService).Assembly)
            };
            ClientToAppManager.Init(new List<OF.DistributeService.Core.Entity.ClientToAppConfig> { 
                estTestApp
            });
        }

        public static void Dispose()
        {
            var instance = ClientToAppManager.Get();
            if (instance != null)
            {
                instance.Dispose();
            }
        }

        static void Application_ApplicationExit(object sender, EventArgs e)
        {
            Dispose();
            Util.LogInfo("ClientDemo Application_ApplicationExit" + e.ToString());
        }

        static void CurrentDomain_DomainUnload(object sender, EventArgs e)
        {
            Dispose();
            Util.LogInfo("ClientDemo CurrentDomain_DomainUnload:" + e.ToString());
        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Dispose();
            Util.LogException("ClientDemo CurrentDomain_UnhandledException:", e.ExceptionObject as Exception);
        }


        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            Dispose();
            Util.LogException("ClientDemo Application_ThreadException:", e.Exception as Exception);
        }
    }

    public class Wather : IWatcher
    {
        public void Process(WatchedEvent @event)
        {
            System.Diagnostics.Debug.WriteLine(@event.Path + "," + @event.State + "," + @event.Type);
        }
    }
}